/* * Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.wso2.carbon.device.mgt.iot.devicecontroller.impl; import org.apache.log4j.Logger; import org.eclipse.paho.client.mqttv3.*; import org.wso2.carbon.device.mgt.iot.config.DeviceConfigurationManager; import org.wso2.carbon.device.mgt.iot.config.DeviceManagementConfig; import org.wso2.carbon.device.mgt.iot.config.DeviceManagementControllerConfig; import org.wso2.carbon.device.mgt.iot.config.controlqueue.DeviceControlQueueConfig; import org.wso2.carbon.device.mgt.iot.devicecontroller.ControlQueueConnector; import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerServiceException; import java.io.File; import java.util.HashMap; // TODO: Auto-generated Javadoc /** * The Class MQTTControlQueue. It is an implementation of the interface * ControlQueueConnector. * This implementation supports publishing of control signals received to an * MQTT end-point. * The configuration settings for the MQTT end-point are read from the * 'controller.xml' file of the project. * This is done using the class 'DefaultDeviceControlConfigs.java' which loads * the settings from the default xml configs file - * /resources/conf/device-controls/controller.xml * * @author smean-MAC */ public class MQTTControlQueue implements ControlQueueConnector, MqttCallback { /** The logger for this class. */ Logger log = Logger.getLogger(MQTTControlQueue.class); /** The control queue (mqtt) endpoint to publish control messages. */ private String CONTROL_QUEUE_ENDPOINT = ""; /** The control queue username. */ private String CONTROL_QUEUE_USERNAME = ""; /** The control queue password. */ private String CONTROL_QUEUE_PASSWORD = ""; /** * Instantiates a new MQTT control queue. */ public MQTTControlQueue() { } /* * (non-Javadoc) * * @see * org.wso2.iot.device.controller.ControlQueueConnector#initControlQueue() */ @Override public void initControlQueue() throws DeviceControllerServiceException { String controlQueue = null; String mqttUrl = ""; String mqttPort = ""; DeviceManagementConfig config = null; try { config = DeviceConfigurationManager.getInstance().getFireAlarmMgtConfig(); // controller configurations DeviceManagementControllerConfig controllerConfig = config.getFireAlarmManagementControllerConfig(); controlQueue = controllerConfig.getDeviceControlQueue(); DeviceControlQueueConfig controlQueueConfig = config.getControlQueuesMap().get(controlQueue); mqttUrl = controlQueueConfig.getEndPoint(); mqttPort = controlQueueConfig.getPort(); CONTROL_QUEUE_ENDPOINT = mqttUrl + ":" + mqttPort; CONTROL_QUEUE_USERNAME = controlQueueConfig.getUserName(); CONTROL_QUEUE_PASSWORD = controlQueueConfig.getPassword(); log.info("CONTROL_QUEUE_ENDPOINT : " + CONTROL_QUEUE_ENDPOINT); } catch (DeviceControllerServiceException ex) { String error = "Error occurred when trying to read configurations file: firealarm-config.xml"; log.error(error, ex); throw new DeviceControllerServiceException(error, ex); } } /* * (non-Javadoc) * * @see * org.wso2.iot.device.controller.ControlQueueConnector#enqueueControls( * java.util.HashMap) */ @Override public void enqueueControls(HashMap<String, String> deviceControls) throws DeviceControllerServiceException { MqttClient client; MqttConnectOptions options; String owner = deviceControls.get("owner"); String deviceType = deviceControls.get("deviceType"); String deviceId = deviceControls.get("deviceId"); String key = deviceControls.get("key"); String value = deviceControls.get("value"); String clientId = owner + "." + deviceId; if (clientId.length() > 24) { String errorString = "No of characters '" + clientId.length() + "' for ClientID: '" + clientId + "' is invalid (should be less than 24, hence please provide a simple 'owner' tag)"; log.error(errorString); throw new DeviceControllerServiceException(errorString); } else { log.info("No of Characters " + clientId.length() + " for ClientID : '" + clientId + "' is acceptable"); } String publishTopic = "wso2" + File.separator + "iot" + File.separator + owner + File.separator + deviceType + File.separator + deviceId; String payLoad = key + ":" + value; try { client = new MqttClient(CONTROL_QUEUE_ENDPOINT, clientId); options = new MqttConnectOptions(); options.setWill("iotDevice/clienterrors", "crashed".getBytes(), 2, true); client.setCallback(this); client.connect(options); log.info("MQTT Client successfully connected to: " + CONTROL_QUEUE_ENDPOINT + ", with client ID - " + clientId); MqttMessage message = new MqttMessage(); message.setPayload(payLoad.getBytes()); client.publish(publishTopic, payLoad.getBytes(), 0, true); log.info("MQTT Client successfully published to topic: " + publishTopic + ", with payload - " + payLoad); client.disconnect(); log.info("MQTT Client disconnected from MQTT broker"); } catch (MqttException ex) { String errorMsg = "MQTT Client Error" + "\n\tReason: " + ex.getReasonCode() + "\n\tMessage: " + ex.getMessage() + "\n\tLocalMsg: " + ex.getLocalizedMessage() + "\n\tCause: " + ex.getCause() + "\n\tException: " + ex; log.error(errorMsg, ex); throw new DeviceControllerServiceException(errorMsg, ex); } } /* * (non-Javadoc) * * @see * org.eclipse.paho.client.mqttv3.MqttCallback#connectionLost(java.lang. * Throwable) */ @Override public void connectionLost(Throwable arg0) { log.error("Connection to MQTT Endpoint Lost"); } /* * (non-Javadoc) * * @see * org.eclipse.paho.client.mqttv3.MqttCallback#deliveryComplete(org.eclipse * .paho.client.mqttv3.IMqttDeliveryToken) */ @Override public void deliveryComplete(IMqttDeliveryToken arg0) { log.info("Published topic: '" + arg0.getTopics()[0] + "' successfully to client: '" + arg0.getClient().getClientId() + "'"); } /* * (non-Javadoc) * * @see * org.eclipse.paho.client.mqttv3.MqttCallback#messageArrived(java.lang. * String, org.eclipse.paho.client.mqttv3.MqttMessage) */ @Override public void messageArrived(String arg0, MqttMessage arg1) throws Exception { log.info("MQTT Message recieved: " + arg1.toString()); } // public static void main(String[] args) { // // HashMap<String, String> myMap = new HashMap<String, String>(); // myMap.put("deviceType", "Arduino"); // myMap.put("owner", "Smeansbeer"); // myMap.put("macAddress", "123456"); // myMap.put("key", "TempSensor"); // myMap.put("value", "123"); // // MQTTControlQueue newInst = new MQTTControlQueue(); // System.out.println(newInst.initControlQueue()); // System.out.println(newInst.enqueueControls(myMap)); // } }